package com.itcam.rpc.server;


import com.itcam.rpc.model.RpcRequest;
import com.itcam.rpc.model.RpcResponse;
import com.itcam.rpc.register.LocalRegistry;
import com.itcam.rpc.serializer.JdkSerializer;
import com.itcam.rpc.serializer.Serializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import javax.xml.ws.handler.MessageContext;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author : Cammy.Wu
 * Description : HTTP请求处理
 */

public class HttpServerHandler implements Handler<HttpServerRequest> {

    @Override
    public void handle(HttpServerRequest request) {
        // 指定序列化器
        final Serializer serializer = new JdkSerializer();

        // 记录日志
        System.out.println("Received request: " + request.method() + " " + request.uri());

        // 异步处理HTTP请求
        request.bodyHandler(body -> {
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 构造响应结果对象
            RpcResponse rpcResponse = new RpcResponse();
            // 如果请求为null,直接返回
            if (null == rpcRequest) {
                rpcResponse.setMessage("rpcRequest is null");
                doResponse(request, serializer, rpcResponse);
                return;
            }

            try {
                // 获取要调用的服务实现类，通过反射调用
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                // 封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setDataType(result.getClass());
                rpcResponse.setMessage("success");
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }
            // 响应
            doResponse(request, serializer, rpcResponse);
        });
    }

    /**
     * 响应
     * @param request
     * @param serializer
     * @param rpcResponse
     */
    private void doResponse(HttpServerRequest request, Serializer serializer, RpcResponse rpcResponse) {
        // 获取请求的响应并设置内容类型为application/json
        HttpServerResponse httpServerResponse = request.response().putHeader("content-type", "application/json");

        try {
            // 序列化RPC响应对象为byte数组
            byte[] serialize = serializer.serialize(rpcResponse);
            // 结束响应并发送序列化后的数据
            httpServerResponse.end(Buffer.buffer(serialize));
        } catch (IOException e) {
            e.printStackTrace();
            // 结束响应但不发送任何数据，表示序列化过程中出现错误
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
